home *** CD-ROM | disk | FTP | other *** search
- INCLUDE \ASM\INCLUDE\BIOS.INC
- INCLUDE DEFS.INC
-
- SAVELEN EQU 160 ; Number of words to save from scn.
- BIOS_SEG EQU 0040H
-
- msv SEGMENT
- ASSUME CS:msv
- ASSUME DS:msv
- ASSUME ES:msv
- ASSUME SS:NOTHING
- ORG 0
- SEG_ORG EQU $
- ORG 100h
- main PROC FAR
- start: jmp init ; Do initialization section
-
- ;*******************************************************************
- ; LANOS VECTOR TSR portion of Message handler --
- ; The LANOS portion simply increments a message received flag and
- ; exits, leaving the actual processing of the message to an
- ; interrupt.
- ;*******************************************************************
- MSV_entry: jmp first ; skip data area
- ; LANOS MSR handler variables
- tsr_name db '■SM'
- color db 70h
- msg_flag db 0
- msg_time dd ?
- old_msr dd ?
-
- ; Pop up Message Service variables
- from db 'From: ',0
- time db 'Time: ',0
- busy db 0 ; TSR status flag
- c_pos dw ? ; old cursor location
- old_vector2 dd ? ; address of previous kbd ISR
- buffer message_buffer <> ; local message buffer
- screen_data dw SAVELEN dup (?) ; storage for old screen data
- old_stk_seg dw ? ; Calling program's stack info
- old_b_ptr dw ?
- old_stk_ptr dw ?
- new_stk_seg dw ?
- new_stk_ptr dw OFFSET TOS
- dw 80 dup (?) ; local stack data area
- TOS equ $
-
- ;************************************************************************
- ; Start of actual LANOS message handler
- ;************************************************************************
- first:
- ; Save current clock count
- cli ; forbid additional interrupts
- push ax ; save needed registers
- push ds
- push si
-
- mov ax,BIOS_SEG
- mov ds,ax ; Point ds to BIOS data area
- mov si,006Ch ; Offset of master clock dw.
-
- mov ax,[si] ; get the first word
- mov word ptr cs:msg_time, ax
-
- inc si ; get the second word
- inc si
- mov ax,[si]
- mov word ptr cs:msg_time + 2,ax
-
- pop si
- pop ds
- pop ax
-
- inc cs:msg_flag ; set the message received flag
-
- call_old_msr:
- sti ; allow interrupts
- jmp cs:old_msr
-
- ;*****************************************************************************
- ; Interrupt E0 handler --- this is apparently something that LANtastic uses
- ; internally to indicate when DOS is safe.
- ;*****************************************************************************
- DOSFREE:
- PUSHF
- CALL CS:old_vector2 ; give everyone else a chance...
-
- cmp cs:msg_flag,0 ; have our services been requested?
- jz Done_E0 ; If not, skip this stuff
- CMP CS:busy,0 ; Are we already busy?
- JNZ Done_E0 ; If so, skip this stuff
-
- ; Activate the pop up routine
- inc cs:busy ; set busy flag
- call pop_up
- mov cs:msg_flag,0 ; reset received flag
- dec cs:busy ; reset busy flag
-
- Done_E0:
- IRET
-
- ;***********************************************************************
- ; Pop-up message handler
- ; When we're popped up, an Esc keypress will take us back to normal
- ; processing
- ;***********************************************************************
- pop_up PROC near
- @NewStack ; replace stack
-
- ; Set all segment regs to CS for convenience
- set_seg:
- push cs ; point all segregs to CS
- push cs
- pop ds
- pop es
-
- ; Save the bottom line of the screen and highlight the message area
- save_cur:
- mov ah,03 ; get old cursor info
- xor bx,bx
- int 10h ; do it;
- mov cs:c_pos,dx ; save old cursor location
-
- mov di,OFFSET screen_data
- mov dx,1700h ; point to line 23
- mov cx,2 ; number of lines to move
- save_row:
- push cx ; save current row count
- mov cx,80 ; number of columns to move
- save_col:
- call CURSOR ; move cursor to proper spot
- push cx ; save char count
- push dx
- @GetChAtr 0 ; get the current character
- stosw ; save current char/attr
- @PutChAtr 32,color,0,1 ; highlight current char position
- pop dx
- inc dl ; increment cursor position
- pop cx ; restore char count
- loop save_col ; go back for next char
-
- xor dl,dl ; set cursor to start of next row
- inc dh
- pop cx ; restore row count
- loop save_row ; go back for next row
-
- ; Get the address of the last unsolicited message
- mov di,OFFSET buffer
- mov ax,5F99H
- int 21h
-
- ; Display the message text
- mov dx,1700h ; point to line 23
- call CURSOR
- mov di,OFFSET buffer.MB_text
- call PRT_STR ; Display the message text
-
- mov dx,1807h ; row 24, column 7
- call CURSOR
- mov di,OFFSET buffer.MB_originator
- call PRT_STR ; Display sender's name
-
- ; display text prompts
- push cs ; point ES to current seg
- pop es
- mov dx,1800h ; line 24, column 0
- call CURSOR
- mov di,OFFSET from ; print from prompt
- call PRT_STR
-
- mov dx,1818h ;line 24, column 24
- call CURSOR
- mov di,OFFSET time ; print time prompt
- call PRT_STR
-
- ; Display the time
- ; load the clock count for use by DIV
- mov ax,word ptr msg_time
- mov dx,word ptr msg_time + 2
-
- push ax ; save count for easy access
- push dx
-
- ; calculate number of minutes since midnight
- mov cx,1080
- div cx
-
- ; calculate error in clock ticks
- mov cx,12
- mul cx
- mov bx,dx ; save high word in bx
- mov cx,ax ; save low word in cx
-
- ; subtract the error from the original clock tick number
- pop dx ; High order word
- pop ax ; low order word
-
- sub ax,cx ; subtract low order word
- sbb dx,bx ; subtract high order word
-
- ; calculate the new, improved number of minutes since midnight
- mov cx,1080
- div cx
-
- ; calculate hours since midnight
- ; leaves hours in AL and minutes in AH
- mov cl,60
- div cl
-
- push ax ; Save result
-
- mov dx,181Eh ; row 24, column 30
- call CURSOR
-
- mov bl,al ; Display hour
- call PRT_TIME
-
- mov al,':' ; display delimiter
- call PUT_CHAR
-
- pop ax
- mov bl,ah ; Display minute
- call PRT_TIME
-
- ; Wait for the user to press escape
- K_WAIT:
- xor ax,ax ; Read keyboard char fn.
- int 16h
-
- cmp al,27 ; is it an escape?
- jne K_WAIT ; If not, try again
-
- ; Restore the bottom line of the screen
- rest_cur:
- mov si,OFFSET screen_data
- mov dx,1700h ; point to line 23
- mov cx,2 ; number of lines to move
- rest_row:
- push cx ; save current row count
- mov cx,80 ; number of columns to move
- rest_col:
- call CURSOR ; move cursor to proper spot
- lodsw ; get the word to save
- push cx ; save char count
- @PutChAtr al,ah,0,1 ; write character/attribute
- inc dl ; increment cursor position
- pop cx ; restore char count
- loop rest_col ; go back for next char
-
- xor dl,dl ; set cursor to start of next row
- inc dh
- pop cx ; restore row count
- loop rest_row ; go back for next row
-
- mov dx,c_pos ; restore old cursor position
- call CURSOR
-
- ; Restore calling program's stack setup
- BYPASS:
- @OldStack ; restore caller's stack
- ret ; return to caller
-
- pop_up ENDP
-
- ;*********************************************************************
- ; Subroutines
- ;********************************************************************
- ; Move cursor -- row in dh, col in dl
- CURSOR PROC NEAR
- push ax
- push bx
- push cx
-
- @SetCurPos dl,dh,0
-
- pop cx
- pop bx
- pop ax
- ret
- CURSOR ENDP
-
- PRT_STR PROC NEAR
- ;
- ; Write ASCIIZ string pointed to by ES:DI at current cursor position
- ;
- L3:
- mov al,es:[di] ; get the character
- or al,al ; See if it's a zero
- jz short L4 ; Yes- we're done
- call PUT_CHAR ; display the character
- inc di ; get the next char
- jmp short L3
- L4:
- ret
- PRT_STR ENDP
-
- ;
- ; Displays a number between 0 and 99 on the screen, at the location
- ; pointed to by es:di. Note that the number must be between 0 and 100.
- ; The number to be displayed must be in bx.
- ;
- PRT_TIME PROC NEAR
- mov ax,bx ; extract the 10's digit
- xor ah,ah ; clear MSB so that we limit range
- mov dl,10
- div dl
- mov dx,ax ; save result
-
- add al,30H ; convert quotient to ASCII
- call PUT_CHAR ; print the digit
-
- mov al,dh ; get remainder (1's digit)
- add al,30H ; convert to ASCII
- call PUT_CHAR ; print the digit
- ret
- PRT_TIME ENDP
-
- ;Print a character (the one in AL, hopefully) and advance the cursor
- PUT_CHAR PROC NEAR
- push dx
- push di
-
- mov ah,0Eh ; write char in tty mode
- mov bx,7 ; video page 0, gfx foreground 7
- int 10h ; display the character
-
- pop di
- pop dx
- ret
- PUT_CHAR ENDP
- LAST_BYTE EQU $
-
- ;
- ; Initialization -- thrown away after load
- ;
-
- title1 db "SoftMagic Resident Message Handler V1.61 for LANtastic",13,10,0
- title2 db "Copyright 1989 by SoftMagic, Inc. All rights Reserved.",13,10,0
- title3 db " LANtastic is a trademark of Artisoft, Inc.",13,10,0
- title4 db 13,10,"The SoftMagic Resident Message Handler is already installed.",13,10,0
-
- IFDEF SHAREWARE
- title5 db "Thanks for trying this unregistered Shareware edition.",7,13,10,0
- ENDIF
-
- init: mov cs:busy,1 ; prevent activation
- @NewStack ; Set up local stack
-
- ; Display title messge
- mov di,OFFSET title1
- call PRT_STR
- mov di,OFFSET title2
- call PRT_STR
- mov di,OFFSET title3
- call PRT_STR
-
- IFDEF SHAREWARE
- mov di,OFFSET title5
- call PRT_STR
- ENDIF
-
- ; Get old LANOS message handler vector
- mov ax,5FE2h
- int 21h
- mov word ptr old_msr,bx ; Save the location of the old vector
- mov word ptr old_msr+2,es
-
- ; See if our message handler is already loaded
- mov di,bx
- add di,3 ; Point to name area
- cmp byte ptr es:[di],254 ; Look for our signature byte
- jnz SHORT install ; is it there?
-
- mov ax,ds
- mov es,ax
- mov di,OFFSET title4
- call PRT_STR
- mov ah,4Ch ; Terminate w/return function
- int 21h ; End the program
-
- ;
- ; Replace the LANOS message service
- ;
-
- install:
- mov ax,cs
- mov es,ax
- mov ax,5FE3h
- mov bx,OFFSET MSV_entry
- int 21H
-
- ;
- ; Replace LANtastic's internal DOS free vector
- ;
- MOV AX,5FE0H
- INT 21H ; GET THE DOS FREE VECTOR
- MOV WORD PTR old_vector2,BX
- MOV WORD PTR old_vector2+2,ES
-
- ;
- ; Set vector to our routine
- ;
- push cs
- pop es
- MOV BX,OFFSET DOSFREE
- MOV AX,5FE1H
- INT 21H
-
- ; Terminate and stay resident
- @OldStack ; Restore caller's stack
- mov cs:busy, 0 ; Enable pop-up
- mov dx,(offset LAST_BYTE - SEG_ORG + 15) shr 4
- mov ah,31h ; free memory and leave
- int 21h
-
- main ENDP
- msv ENDS
- END start
-